package com.yonyou.pmclouds.basecom.filter;

import com.yonyou.pmclouds.basecom.conf.MobileFilterConfiguration;
import com.yonyou.pmclouds.basecom.multilanguage.Language;
import com.yonyou.pmclouds.basecom.runtime.RpcUtils;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.view.BuziExWrapObject;
import com.yonyou.yht.sdk.UserCenter;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 移动端请求过滤器
 * 1.过滤移动端发来的请求，以/mobile开头
 * 2.不需要参与过滤的路径在MobileFilterConfiguration中配置，多路径以","分隔
 * 3.校验token，移动端请求需要在传过来的参数中加上access_token
 *
 * @author zhangwce
 */
@Slf4j
public class MobileTokenCheckFilter implements Filter {

    // 不参与过滤的路径
    private String[] ignoreUrlArray = new String[]{};

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        boolean isIgnoreUrl = checkIgnoreUrl(httpServletRequest);

        if (isIgnoreUrl) {
            filterChain.doFilter(request, response);
            // 设置语言，目前按照中文处理,避免出现问题
            RuntimeEnvironment.setLanguage(Language.SIMPLIFIEDCHINESE);
        } else {
            String access_token = getAccessToken(httpServletRequest);
            log.debug("获取到的请求token为："+access_token);
//			initMobContext(access_token);
            checkAccessToken(access_token, request, response, filterChain);
        }
    }

    /**
     * 检查token是否有效
     *
     * @param access_token
     * @param request
     * @param response
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    private void checkAccessToken(String access_token, ServletRequest request, ServletResponse response,
                                  FilterChain filterChain) throws IOException, ServletException {
        JSONObject tokenCheckResult = JSONObject.fromObject(UserCenter.checkOauthToken(access_token));

        //status == 0   校验失败;status == 1   校验成功
        if (0 == tokenCheckResult.getInt("status")) {
            log.error("accessToken校验失败，错误信息为：" + tokenCheckResult.getString("msg"));
            JSONObject timeOutResult = JSONObject
                    .fromObject(new BuziExWrapObject("token timeout", tokenCheckResult.getString("msg")));

            PrintWriter writer = response.getWriter();
            writer.write(timeOutResult.toString());
        } else {
            initMobContext(access_token, ((HttpServletRequest)request).getHeader("tenant-id"));
            filterChain.doFilter(request, response);
        }
    }

    /**
     * 初始化环境变量
     *
     * @param access_token
     */
    private void initMobContext(String access_token, String tenantId) {

        String userInfo = UserCenter.getUserByToken(access_token);

        JSONObject userJson = JSONObject.fromObject(userInfo);

        String userid = userJson.get("user") == null ? null
                : (String) ((JSONObject) userJson.get("user")).get("userId");

        // userid为空，解析用户失败
        if (StringUtils.isEmpty(userid))
            log.info("友互通用access_token解析用户id失败, access_token: {}, 解析结果userInfo：{}", access_token, userInfo);

//		 String tenantInfo = TenantCenter.getLoginTenants(userid, "pm_cloud");
//		 
//		 System.out.println("tenantInfo:"+tenantInfo);

        // 获取当前登录用户id
        RuntimeEnvironment.setLoginUserId(userid);
        // 获取当前数据中心
        RuntimeEnvironment.setTenantId(tenantId == null ? "" : tenantId);
        // 设置语言，目前按照中文处理
        RuntimeEnvironment.setLanguage(Language.SIMPLIFIEDCHINESE);
        // 将数据塞入rpc的上下文中
        RpcUtils.setRpcContextFromRuntimeEnv();


    }

    /**
     * 从请求中获取token信息
     *
     * @param httpServletRequest
     * @return
     */
    private String getAccessToken(HttpServletRequest httpServletRequest) {

        String access_token = httpServletRequest.getHeader("access-token");
        if (access_token == null || "".equals(access_token)) {
            access_token = httpServletRequest.getParameter("access-token");
        }

        return access_token;
    }

//	private String getRequestParams(HttpServletRequest httpServletRequest) {
//		StringBuilder sb = new StringBuilder();
//		try (BufferedReader reader = httpServletRequest.getReader();) {
//			char[] buff = new char[1024];
//			int len;
//			while ((len = reader.read(buff)) != -1) {
//				sb.append(buff, 0, len);
//			}
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		return sb.toString();
//	}

    /**
     * 检查请求路径是否为不需过滤的路径
     *
     * @param httpServletRequest
     * @return
     */
    private boolean checkIgnoreUrl(HttpServletRequest httpServletRequest) {
        boolean isIgnoreUrl = false;
        if (ignoreUrlArray != null && ignoreUrlArray.length > 0) {
            String currentPath = httpServletRequest.getServletPath();
            for (String ignoreUrl : ignoreUrlArray) {
                if (currentPath.startsWith(ignoreUrl.replace("*", ""))) {
                    isIgnoreUrl = true;
                    break;
                }
            }
        }
        return isIgnoreUrl;
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        // 得到不参与过滤的请求路径，例如：移动端登录路径
        String ignoreUrls = config.getInitParameter(MobileFilterConfiguration.IGNORE_TOKEN_URLS_PARAMTER);
        ignoreUrlArray = ignoreUrls.split(",");

    }

}
